//
//  NSString+Json.m
//
//  Created by BruceYu on 14-8-19.
//  Copyright (c) 2014年 BruceYu. All rights reserved.
//

#import "NSString+Json.h"
#import <objc/runtime.h>
@implementation NSString (Json)

- (NSDictionary *)jsonDictionary
{
    return [self JSONValue];
}

- (NSArray *)jsonArray
{
    return [self JSONValue];
}

- (id)JSONValue
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSError *__autoreleasing error = nil;
    id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    if (error != nil) return nil;
    return result;
}


@end



@implementation NSDictionary (JsonString)

-(NSString *)jsonString{
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
                                                       options:NSJSONWritingPrettyPrinted
                                                         error:&error];
    if (jsonData == nil) {
#ifdef DEBUG
        NSLog(@"fail to get JSON from dictionary: %@, error: %@", self, error);
#endif
        return nil;
    }
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    return jsonString;
}

@end


@implementation NSArray (JsonString)
-(NSString *)jsonString
{
    
    NSError *error = nil;
    
    NSData *jsonData = [NSJSONSerialization
                        dataWithJSONObject:self options:NSJSONWritingPrettyPrinted error:&error];
    //NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
    //                                                   options:kNilOptions
    //                                                     error:&error];
    
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    if (jsonString) {
        return jsonString;
    }
    return @"";
}


@end



@implementation NSObject (LHModelOperation)
- (NSArray*)getAllPropertyName//runtime获取model所有属性
{
    NSMutableArray* nameArray = [NSMutableArray array];
    unsigned int count = 0;
    objc_property_t *property_t = class_copyPropertyList([self class], &count);
    for (int i=0; i<count;++i) {
        objc_property_t propert = property_t[i];
        const char * propertyName = property_getName(propert);
        [nameArray addObject:[NSString stringWithUTF8String:propertyName]];
    }
    free(property_t);
    return nameArray;
}
//创建get方法
- (SEL)createGetSelectorWith:(NSString*)propertyName
{
    return NSSelectorFromString(propertyName);
}
//创建set方法
- (SEL)createSetSEL:(NSString*)propertyName
{
    NSString* firstString = [propertyName substringToIndex:1].uppercaseString;
    propertyName = [propertyName stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:firstString];
    propertyName = [NSString stringWithFormat:@"set%@:",propertyName];
    return NSSelectorFromString(propertyName);
}
//执行get方法
- (id)getResultWithPropertName:(NSString*)propertyName
{
    SEL getSel = [self createGetSelectorWith:propertyName];
    if ([self respondsToSelector:getSel]) {
        //获取类和方法签名
        NSMethodSignature* signature = [self methodSignatureForSelector:getSel];
        const char * returnType = [signature methodReturnType];
        //获取调用对象
        NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
        [invocation setTarget:self];
        [invocation setSelector:getSel];
        [invocation invoke];
        if (!memcmp(returnType, "@", 1)) {
            NSObject *__unsafe_unretained returnValue = nil;
            [invocation getReturnValue:&returnValue];
            return returnValue;
        }else if (!memcmp(returnType, "i", 1)||!memcmp(returnType, "q", 1)||!memcmp(returnType, "Q", 1)){
            int returnValue = 0;
            [invocation getReturnValue:&returnValue];
            return [NSString stringWithFormat:@"%d",returnValue];
        }else if(!memcmp(returnType, "f", 1)){
            float returnValue = 0.0;
            [invocation getReturnValue:&returnValue];
            return [NSString stringWithFormat:@"%g",returnValue];
        }else if (!memcmp(returnType, "d", 1)) {
            double retureVaule = 0.0;
            [invocation getReturnValue:&retureVaule];
            return [NSString stringWithFormat:@"%g",retureVaule];
        }
        
    }
    return nil;
}

//mode转字典
- (NSDictionary*)getDic
{
    NSArray* nameArray = [self getAllPropertyName];
    NSMutableDictionary* dic = [NSMutableDictionary dictionary];
    for (NSString* propertyName in nameArray) {
        id value = [self getResultWithPropertName:propertyName];
        [dic setValue:value forKey:propertyName];
    }
    return dic;
}

//字典转model
+ (id)modelWithDictory:(NSDictionary*)dic
{
    id model = [[self alloc] init];
    NSArray* nameArray = dic.allKeys;
    for (int i=0; i < nameArray.count; ++i) {
        SEL setSel = [model createSetSEL:nameArray[i]];
        if ([model respondsToSelector:setSel]) {
            
            NSMethodSignature* signature = [model methodSignatureForSelector:setSel];
            const char* c = [signature getArgumentTypeAtIndex:2];
            if (!memcmp(c, "@", 1)) {
                IMP imp = [model methodForSelector:setSel];
                void (*func) (id,SEL,id) = (void*)imp;
                func(model, setSel,dic[nameArray[i]]);
            }else if (!memcmp(c, "i", 1)||!memcmp(c, "q", 1)||!memcmp(c, "Q", 1)){
                int value = [dic[nameArray[i]] intValue];
                IMP imp = [model methodForSelector:setSel];
                void (*func) (id,SEL,int) = (void*)imp;
                func(model, setSel,value);
            }else if(!memcmp(c, "f", 1)){
                float value = [dic[nameArray[i]] floatValue];
                IMP imp = [model methodForSelector:setSel];
                void (*func) (id,SEL,float) = (void*)imp;
                func(model, setSel,value);
            }else if (!memcmp(c, "d", 1)) {
                double value = [dic[nameArray[i]] doubleValue];
                IMP imp = [model methodForSelector:setSel];
                void (*func) (id,SEL,double) = (void*)imp;
                func(model, setSel,value);
            }
        }
    }
    return model;
}

@end

@implementation NSString (data)

-(NSData *)dataUTF8String{
    return [self dataUsingEncoding:NSUTF8StringEncoding];
}


@end


@implementation NSString (Separated)
-(NSArray *)onArraybyString:(NSString *)string{
    NSArray *array = [self componentsSeparatedByString:string];
    return array?array:nil;
}

@end

@implementation NSObject (ID)

-(NSString *)Id{
    if ([self isKindOfClass:[NSString class]]) {
        NSString *str = (id)self;
        return str;
    }
    else if ([self isKindOfClass:[NSNumber class]]){
        NSNumber *str = (id)self;
        return [str stringValue];
    }
    return nil;
}

@end


@implementation NSString (url)

+(id)urlWithDic:(NSDictionary *)dictionary
{
    if (![dictionary isKindOfClass:[NSDictionary class]]) {
        return @"";
    }
    NSEnumerator * enumerator = [dictionary keyEnumerator];
    //定义一个不确定类型的对象
    NSString * key;
    id value;
    //遍历输出
    while(key = [enumerator nextObject])
    {
        //在这里我们得到的是键值，可以通过（1）得到，也可以通过这里得到的键值来得到它对应的value值
        //通过NSDictionary对象的objectForKey方法来得到
        //其实这里定义objectValue这个对象可以直接用NSObject，因为我们已经知道它的类型了，id在不知道类型的情况下使用
        NSString * objectValue = [dictionary objectForKey:key];
        if(objectValue != nil)
        {
            NSString *urlStr = [NSString stringWithFormat:@"%@=%@",key,objectValue];
            if(value ==nil)
            {
                value =urlStr;
            }else
            {
                value = [NSString stringWithFormat:@"%@&%@",value,urlStr];
                urlStr = nil;
            }
        }
        
    }
    
    return value;
    
}

@end

@implementation NSData (Encrypt)

-(NSString *)UTF8String{
    return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];
}

- (BOOL)isEmpty {
    return [self length] == 0;
}

@end


@implementation NSData (Array)
-(NSArray *)onArrayByData{
    NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:self];
    return array?array:nil;
}

-(UIImage *)onImageByData{
    UIImage *image = [UIImage imageWithData:self];
    return image?image:nil;
}

@end



@implementation NSURL (string)
-(NSString *)onStringByURL{
    NSString *string = self.absoluteString;
    return string?string:nil;
}
-(NSData *)onDataByURL{
    NSData *data = [NSData dataWithContentsOfURL:self];
    return data?data:nil;
}
@end

@implementation NSURL (data)

-(NSData *)onDataByURL{
    NSData *data = [NSData dataWithContentsOfURL:self];
    return data?data:nil;
}
@end
